<script setup>
import {getCurrentInstance, onMounted} from 'vue';
import {useRouter} from 'vue-router';
import {VueFlow, useVueFlow} from "@vue-flow/core";
import {Panel, MarkerType} from "@vue-flow/core";
import {Background, MiniMap, Controls} from "@vue-flow/additional-components";
import {ref, toRef} from 'vue'
import {nanoid} from 'nanoid'


import '../css/taskflow.css'
import {
  getCheckpointByID,
  saveCheckpointList,
  getCheckpointList,
} from "src/utils/config";
import CustomEdge from "components/CustomEdge.vue";
import ItemNode from "components/ItemNode.vue";
import UploadImage from "components/UploadImage.vue";
import {Dialog} from "quasar";

const {addNodes, setNodes, removeNodes} = useVueFlow()
const {addEdges, setEdges, updateEdge, removeEdges} = useVueFlow()
const {onConnect, onPaneReady, setTransform, onNodeDragStop, toObject} = useVueFlow()
const $router = useRouter();


const elements = ref([])
let taskinfo = ref({})

// UI
const viewCustomer = ref(false)
const tab = ref('one')
const splitterModel = ref(20)
const tree_selected = ref('Food')
const checkpoint_tree = ref([])
const initTreeFlag = ref(false)
const current_point_name = ref('')
const show_detail = ref(false)

let checkpoint = {}
let task_list = []
let checkpoint_list = []

onMounted(() => {
  let welcome_tree = []
  let main_tree = []
  let sub_tree = []

  checkpoint_list = getCheckpointList()
  checkpoint_list.forEach(function (checkpoint) {
    switch (checkpoint.group) {
      case 'WELCOME':
        welcome_tree.push({
          label: checkpoint.name + '(' + checkpoint.code + ')',
          code: checkpoint.id,
        });
        break;

      case 'MAIN':
        main_tree.push({
          label: checkpoint.name + '(' + checkpoint.code + ')',
          code: checkpoint.id,
        });
        break;

      case 'SUB':
        sub_tree.push({
          label: checkpoint.name + '(' + checkpoint.code + ')',
          code: checkpoint.id,
        });
        break;
    }
  })

  // 展示导航数据
  const tree = [
    {
      label: '场地列表',
      children: [
        {
          label: '欢迎页面',
          // code: 'WELCOME',
          children: welcome_tree,
        },
        {
          label: '主线场地',
          // code: 'MAIN',
          children: main_tree,
        },

      ]
    }
  ]
  if (sub_tree.length > 0) {
    tree[0].children.push({
          label: '支线场地',
          // code: 'SUB',
          children: sub_tree,
        },
    )
  }
  console.log(tree)
  checkpoint_tree.value = tree
  // console.log(tree_checkpoint.value)
  initTreeFlag.value = true
});

function getTempCode() {
  let count = task_list.length + 1
  let code = count.toString()
  let s = 4 - code.length
  let c = ''
  for (let i = 1; i < s; i++) {
    c += '0'
  }

  return 'T' + c + code
}

function toRefs(obj) {
  const ret = {}
  // 使用for...in 循环遍历对象
  for (const key in obj) {
    // 逐个调用toRef完成转换
    ret[key] = toRef(obj, key).value
  }
  return ret
}

function onReset() {
  taskinfo.value.memo = ''
  taskinfo.value.content = ''
  taskinfo.value.content_css = ''
  taskinfo.value.image = ''
  taskinfo.value.image_css = ''
  taskinfo.value.front_image = ''
  taskinfo.value.front_image_css = ''
}

function onMenuClick(e) {
  // console.log('menu click', tree_selected.value)
  // return;
  if (tree_selected.value === undefined) {
    return
  }
  let code = tree_selected.value

  console.log('checkpoint code', code)
  checkpoint = getCheckpointByID(checkpoint_list, code)
  current_point_name.value = checkpoint.name
  console.log('checkpoint', checkpoint)

  // 加载已经保存的布局
  showConfigFlow()

  // setTimeout(() => {
  //   vueInstance.fitView({padding: 0.25, includeHiddenNodes: true})
  // }, 100)
}

function onRemoveNode() {
  console.log('remove', taskinfo.value.code)
  Dialog.create({
    title: '提示',
    message: '你确定要删除吗？',
    cancel: true,
    persistent: true
  }).onOk(() => {
    removeNodes(taskinfo.value.code)
    viewCustomer.value = false
  })
}

function onSaveNodeInfo() {
  saveCheckpointFlow()
  viewCustomer.value = false
}

function getFlowByCode(code) {
  let workFlow = []
  let nextCodeList = [code]

  while (nextCodeList.length > 0) {
    // console.log('nextCodeList', nextCodeList)
    let taskCode = nextCodeList[0]
    let task = getTaskFromNode(taskCode)
    nextCodeList = getNextTaskCodeByEdge(taskCode)

    if (nextCodeList.length === 1) {
      // 正常节点，直接压入队列
      workFlow.push(task)
    } else {
      // 分支节点，需要补充分支选项
      let item_list = []

      nextCodeList.forEach(function (taskCode, index) {
        let itemTask = getTaskFromNode(taskCode)
        // TODO：应该判断是否是分支
        // console.log('item node', taskCode, itemTask)
        nextCodeList = getNextTaskCodeByEdge(itemTask.code)
        item_list.push({
          code: itemTask.code,
          content: itemTask.content,
          prompt: itemTask.prompt,
          flow: getFlowByCode(nextCodeList[0])
        })
      })

      task.item_list = item_list
      workFlow.push(task)
      break
    }
  }

  return workFlow
}


function getNextTaskCodeByEdge(code) {
  const all = toObject()
  let nextCode = []
  for (let index = 0; index < all.edges.length; index++) {
    let edge = all.edges[index]
    if (edge.source === code) {
      nextCode.push(edge.target)
    }
  }

  return nextCode
}

function getTaskFromNode(code) {
  // console.log('get task', code)
  const all = toObject()
  for (let index = 0; index < all.nodes.length; index++) {
    if (all.nodes[index].id === code) {
      // console.log('get task node', all.nodes[index])
      return all.nodes[index].data
    }
  }
}

// vue flow 绑定事件
onConnect((params) => {
  // console.log('connect', params)
  // params
  addEdges({
    source: params.source,
    target: params.target,
    type: 'custom',
    markerEnd: MarkerType.ArrowClosed
  })

  saveCheckpointFlow()
})

onNodeDragStop((params) => {
  console.log('on drag stop')
  saveCheckpointFlow()
})

let vueInstance = {}
onPaneReady((instance) => {
  // console.log('instance', instance)
  vueInstance = instance
})

function onNodeClick(node) {
  console.log('on node click', node.node.data)
  // console.log(getCurrentInstance())
  taskinfo.value = node.node.data
  viewCustomer.value = true
}

function saveFlow() {
  // 保存用户操作的节点
  checkpoint.flow = toObject()

  let nextCodeList = getNextTaskCodeByEdge('0000')
  if (nextCodeList.length === 1) {
    // 默认任务起始节点
    let workflow = getFlowByCode(nextCodeList[0])
    console.log('work flow', workflow)
    checkpoint.workflow = {
      flow: workflow,
      step: 0,
    }
  }

  // 保存到本地缓存
  saveCheckpointList(checkpoint_list)
}

async function showConfigFlow() {
  const flow = checkpoint.flow

  // 清理原始数据
  await removeNodes(toObject().nodes)
  console.log('clear')

  if (flow) {
    // 重新绑定事件
    flow.nodes.forEach(function (node) {
      // console.log('node', node)
      if (node.type === 'custom') {
        node.events = {click: onNodeClick}
      } else {
        node.data = {}
      }
      // TODO：修改节点默认字段
      // console.log(node)
      // node.data.image_css = 'bg bg-center'
    })

    setNodes(flow.nodes)
    setEdges(flow.edges)
  } else {
    // 开始节点
    addNodes({
      id: '0000',
      label: checkpoint.name,
      type: 'input',
      position: {x: 100, y: 100},
    })

  }
}

async function initFlowNode() {
  await removeNodes(toObject().nodes)
  await removeEdges(toObject().edges)

  // 开始节点
  addNodes({
    id: '0000',
    label: checkpoint.name,
    type: 'input',
    position: {x: 100, y: 100},
  })
}

function saveCheckpointFlow() {
  // console.log('all object', toObject())
  // console.log('checkpoint', checkpoint)
  // console.log('checkpoint list', checkpoint_list)

  // 保存用户操作的节点
  checkpoint.flow = toObject()

  let nextCodeList = getNextTaskCodeByEdge('0000')
  if (nextCodeList.length === 1) {
    // 默认任务起始节点
    let workflow = getFlowByCode(nextCodeList[0])
    console.log('work flow', workflow)
    checkpoint.workflow = {
      flow: workflow,
      step: 0,
    }
  }

  // 保存本地列表
  saveCheckpointList(checkpoint_list)
}

function addTaskNode(data) {
  console.log('add task', data)

  addNodes({
    id: data.code,
    data: data,
    type: 'custom',
    position: {x: 1, y: 100},
    events: {click: onNodeClick}
  })

  saveCheckpointFlow()
}

function addTaskMessage() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 100,
    memo: '图文卡',
    content: '',
    content_css: '',
    image: '',
    image_css: '',
    front_image: '',
    front_image_css: '',
  }

  addTaskNode(operationTask)
}

function addTaskGPS() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 101,
    memo: 'GPS卡',
    content: '',
    content_css: '',
    image: '',
    image_css: '',
    front_image: '',
    front_image_css: '',
    gps: '',
    range: 70,
  }

  addTaskNode(operationTask)
}

function addTaskBeacon() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 102,
    memo: '蓝牙卡',
    content: '',
    content_css: '',
    image: '',
    image_css: '',
    front_image: '',
    front_image_css: '',
    beacon: '',
    rssi: 100,
  }

  addTaskNode(operationTask)
}

function addTaskCheck() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 103,
    memo: '确认卡',
    content: '',
    content_css: '',
    image: '',
    image_css: '',
    front_image: '',
    front_image_css: '',
    confirm: '',
  }

  addTaskNode(operationTask)
}

function addTaskQuestion() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 200,
    memo: '选择卡',
    content: '',
    content_css: '',
    image: '',
    image_css: '',
    front_image: '',
    front_image_css: '',
  }

  addTaskNode(operationTask)
}

function addTaskQuestionItem() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 201,
    memo: '分支卡',
    content: '',
  }

  addTaskNode(operationTask)
}

function addTaskOperationExit() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 300,
    memo: '结束卡',
    content: 'exit'
  }

  addTaskNode(operationTask)
}

function addTaskOperation() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 301,
    memo: '晋级卡',
    content: ''
  }

  addTaskNode(operationTask)
}

function addTaskKeys() {
  const operationTask = {
    code: nanoid(),
    checkpoint: checkpoint.id,
    type: 104,
    memo: '密钥卡',
    content: '',
    content_css: '',
    image: '',
    image_css: '',
    front_image: '',
    front_image_css: '',
  }

  addTaskNode(operationTask)
}

</script>
<template>
  <q-page class="q-pa-md">
    <q-splitter v-model="splitterModel" style="height: 90vh">

      <template v-slot:before>
        <q-tree
            v-if="initTreeFlag"
            :nodes="checkpoint_tree"
            node-key="code"
            label-key="label"
            selected-color="primary"
            v-model:selected="tree_selected"
            default-expand-all
            @click="onMenuClick"
        />
      </template>

      <template v-slot:after>
        <q-toolbar class="text-primary">
          <!--          <q-btn flat round dense icon="menu" />-->
          <q-toolbar-title>
            {{ current_point_name }}
          </q-toolbar-title>
          <q-btn-dropdown stretch flat label="Dropdown">
            <q-list>
              <q-item-label header>Folders</q-item-label>
              <q-item v-for="n in 3" :key="`x.${n}`" clickable v-close-popup tabindex="0">
                <q-item-section avatar>
                  <q-avatar icon="folder" color="secondary" text-color="white" />
                </q-item-section>
                <q-item-section>
                  <q-item-label>Photos</q-item-label>
                  <q-item-label caption>February 22, 2016</q-item-label>
                </q-item-section>
                <q-item-section side>
                  <q-icon name="info" />
                </q-item-section>
              </q-item>
              <q-separator inset spaced />
              <q-item-label header>Files</q-item-label>
              <q-item v-for="n in 3" :key="`y.${n}`" clickable v-close-popup tabindex="0">
                <q-item-section avatar>
                  <q-avatar icon="assignment" color="primary" text-color="white" />
                </q-item-section>
                <q-item-section>
                  <q-item-label>Vacation</q-item-label>
                  <q-item-label caption>February 22, 2016</q-item-label>
                </q-item-section>
                <q-item-section side>
                  <q-icon name="info" />
                </q-item-section>
              </q-item>
            </q-list>
          </q-btn-dropdown>

          <q-btn @click="addTaskMessage" color="secondary" stretch flat label="图文卡"/>
          <q-btn @click="addTaskGPS" color="secondary" stretch flat label="GPS卡"/>
          <q-btn @click="addTaskBeacon" color="secondary" stretch flat label="蓝牙卡"/>
          <q-btn @click="addTaskCheck" color="secondary" stretch flat label="确认卡"/>
          <q-btn @click="addTaskKeys" color="secondary" stretch flat label="密钥卡"/>
          <q-btn @click="addTaskQuestion" color="secondary" stretch flat label="选择卡"/>
          <q-btn @click="addTaskQuestionItem" color="secondary" stretch flat label="分支卡"/>
          <q-btn @click="addTaskOperation" color="secondary" stretch flat label="晋级卡"/>
          <q-btn @click="addTaskOperationExit" color="secondary" stretch flat label="结束卡"/>
          <q-toggle v-model="show_detail" label="任务详情"/>
        </q-toolbar>
        <q-card class="q-pa-md" style="height: 84vh">
          <VueFlow class="basicflow2" v-model="elements" :default-viewport="{ zoom: 1 }" :min-zoom="0.2" :max-zoom="4">
            <Background pattern-color="#aaa" gap="8"/>
            <MiniMap/>
            <Controls/>

            <template #node-custom="props">
              <ItemNode v-bind="props" :detail="show_detail"/>
            </template>

            <template #edge-custom="props">
              <CustomEdge v-bind="props"/>
            </template>
          </VueFlow>

        </q-card>

      </template>

    </q-splitter>

    <q-dialog v-model="viewCustomer">
      <q-card bordered class="my-card">
        <q-card-section class="bg-primary text-white full-width">
          <div class="text-h6">详情</div>
        </q-card-section>

        <q-separator class="q-px-md" inset></q-separator>

        <q-card-section class="q-pt-md full-width">
          <q-list>
            <q-item>
              <q-item-section>
                <q-input v-model="taskinfo.memo" label="备注"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type!==300">
              <q-item-section>
                <q-input :type="taskinfo.type > 200 ? '' : 'textarea'" v-model="taskinfo.content" label="内容"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type<201">
              <q-item-section>
                <q-input v-model="taskinfo.content_css" label="样式"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type===101">
              <q-item-section>
                <q-input v-model="taskinfo.gps" label="GPS"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type===101">
              <q-item-section>
                <q-input type="number" v-model="taskinfo.range" label="距离范围"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type===102">
              <q-item-section>
                <q-input v-model="taskinfo.beacon" label="Beacon编码"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type===102">
              <q-item-section>
                <q-input type="number" v-model="taskinfo.rssi" label="信号强度"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type===103">
              <q-item-section>
                <q-input v-model="taskinfo.confirm" label="确认信息"/>
              </q-item-section>
            </q-item>

            <q-item v-if="taskinfo.type===201">
              <q-item-section>
                <q-input v-model="taskinfo.prompt" label="提示信息"/>
              </q-item-section>
            </q-item>

          </q-list>
        </q-card-section>


        <q-card-section class="q-pt-md full-width" v-if="taskinfo.type<201||taskinfo.type===302">
          <upload-image v-model="taskinfo.front_image" title="前景图"></upload-image>
          <q-input v-model="taskinfo.front_image_css" label="样式"/>
        </q-card-section>

        <q-card-section class="q-pt-md full-width" v-if="taskinfo.type<201||taskinfo.type===302">
          <upload-image v-model="taskinfo.image" title="背景图"></upload-image>
          <q-input v-model="taskinfo.image_css" label="样式"/>
        </q-card-section>

        <q-card-actions align="right">
          <!--          <q-btn color="secondary" @click="onReset">重置</q-btn>-->
          <q-btn color="deep-orange" @click="onRemoveNode">删除</q-btn>
          <q-btn color="primary" @click="onSaveNodeInfo">保存</q-btn>
        </q-card-actions>
      </q-card>
    </q-dialog>

  </q-page>
</template>

<style lang="sass" scoped>
.my-card
  width: 100%
  max-width: 900px
</style>
